package com.hz.tgb.response.restful.config;

import com.hz.tgb.response.restful.ResponseData;
import com.hz.tgb.response.restful.annotation.PropertyFiltration;
import com.monitorjbl.json.DefaultView;
import com.monitorjbl.json.JsonResult;
import com.monitorjbl.json.JsonView;
import com.monitorjbl.json.JsonViewReturnValueHandler;
import com.monitorjbl.json.Match;
import org.springframework.core.MethodParameter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.ModelAndViewContainer;

import java.util.List;

/**
 * 响应结果过滤
 *
 * @author hezhao on 2019/8/28 18:10
 */
public class MyJsonViewReturnValueHandler extends JsonViewReturnValueHandler {
    private JsonResult json = JsonResult.instance();

    public MyJsonViewReturnValueHandler(List<HttpMessageConverter<?>> converters, DefaultView defaultView) {
        super(converters, defaultView);
    }

    @Override
    public void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
        super.handleReturnValue(convertReturnValue(returnValue, returnType), returnType, mavContainer, webRequest);
    }

    private Object convertReturnValue(Object source, MethodParameter returnType) {
        if(source instanceof ResponseData) {
            ResponseData responseData = (ResponseData) source;
            responseData.setTraceId("// TODO context.getTraceId()");
        }

        if (!returnType.getMethod().isAnnotationPresent(PropertyFiltration.class)) {
            return source;
        }

        PropertyFiltration serializedField = returnType.getMethodAnnotation(PropertyFiltration.class);
        Class<?> cls = serializedField.clazz();

        if (cls.isAssignableFrom(Void.class)) {
            cls = returnType.getParameterType();
        }

        String[] includes = serializedField.includes();
        String[] excludes = serializedField.excludes();

        Match match = Match.match();
        if (excludes.length > 0) {
            match.exclude(excludes);
        }
        if (includes.length > 0) {
            match.include(includes);
        }

        return json.use(JsonView.with(source).onClass(cls, match)).returnValue();
    }


}
